package cn.iocoder.yudao.module.member.service.auth;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.member.convert.auth.MemberShopAuthConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.auth.MemberShopAuthDO;
import cn.iocoder.yudao.module.member.dal.mysql.auth.MemberShopAuthMapper;
import cn.iocoder.yudao.module.member.enums.MemberAuthBizTypeEnum;
import cn.iocoder.yudao.module.member.enums.MemberAuthShopBizTypeEnum;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantOnlyCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tenantdetail.vo.TenantDetailCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.userdetail.vo.UserDetailCreateReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenantdetail.TenantDetailDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.dataobject.userdetail.UserDetailDO;
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
import cn.iocoder.yudao.module.system.service.permission.RoleService;
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
import cn.iocoder.yudao.module.system.service.tenantdetail.TenantDetailService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.module.system.service.userdetail.UserDetailService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.Valid;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;
import cn.iocoder.yudao.module.member.controller.admin.auth.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.auth.MemberAuthDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.module.member.convert.auth.MemberAuthConvert;
import cn.iocoder.yudao.module.member.dal.mysql.auth.MemberAuthMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;

/**
 * 会员认证大愚灸术学员 Service 实现类
 *
 * @author 曹建伟
 */
@Service
@Validated
public class DayuAuthServiceImpl implements DayuAuthService{

    @Resource
    private MemberAuthMapper authMapper;

    @Resource
    private MemberShopAuthMapper shopAuthMapper;

    @Resource
    private MemberUserApi memberUserApi;

    @Resource
    private MemberUserService memberUserService;

    @Resource
    private AdminUserService adminUserService;

    @Resource
    private TenantService tenantService;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private UserDetailService userdetailservice;

    @Resource
    private TenantDetailService tenantDetailService;

    @Resource
    private RoleService roleService;

    @Resource
    private PermissionService permissionService;

    /**
     * 对密码进行加密
     *
     * @param password 密码
     * @return 加密后的密码
     */
    private String encodePassword(String password) {
        return passwordEncoder.encode(password);
    }

    @Override
    public Long createAuth(MemberAuthCreateReqVO createReqVO) {
        Long memberId = createReqVO.getMemberId();

        MemberAuthDO memberAuthDO = authMapper.selectOne(new LambdaQueryWrapperX<MemberAuthDO>()
                .eq(MemberAuthDO::getMemberId, memberId));

        if(memberAuthDO != null) {
            if(memberAuthDO.getStatus() == MemberAuthBizTypeEnum.AUTH.getType()){
                throw exception(MEMBER_AUTH_EXISTS);
            }
        }

        MemberUserRespDTO memberUserRespDTO = memberUserApi.getUser(memberId);
        if(memberUserRespDTO == null){
            throw exception(MEMBER_NOT_EXISTS);
        }

        if(memberUserRespDTO.getMobile() == null){
            throw exception(MEMBER_NOT_BAND_MOBILE);
        }

        AdminUserDO adminUserDO = adminUserService.getUserByMobile(memberUserRespDTO.getMobile());
        if(adminUserDO != null){
            throw exception(MEMBER_HAS_BIND_USER);
        }

        // 插入
        MemberAuthDO auth = MemberAuthConvert.INSTANCE.convert(createReqVO);
        authMapper.insert(auth);
        // 返回
        return auth.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditMemberAuth(Long id, MemberAuthBizTypeEnum status, String reason){
        validateAuthExists(id);

        // 1:审核通过 2:审核拒绝 3：参数错误
        //todo 短信通知
        if(status.getType() == MemberAuthBizTypeEnum.SUCCESS.getType()){
            MemberAuthDO memberAuthDO = authMapper.selectById(id);
            memberAuthDO.setStatus(MemberAuthBizTypeEnum.SUCCESS.getType());
            authMapper.updateById(memberAuthDO);

            MemberUserRespDTO memberUserRespDTO = memberUserApi.getUser(memberAuthDO.getMemberId());

            // 1 创建user
            UserCreateReqVO userCreateReqVO = MemberAuthConvert.INSTANCE.convertUserVO(memberAuthDO, memberUserRespDTO, memberUserRespDTO.getMobile());
            Long userId = adminUserService.createUser(userCreateReqVO);
            AdminUserDO adminUserDO = adminUserService.getUser(userId);

            // 1.2添加权限
            RoleDO roleDO = roleService.getRoleByName("认证会员");
            Set<Long> roleIds = new HashSet<>();
            roleIds.add(roleDO.getId());
            permissionService.assignUserRole(userId, roleIds);

            // 2 创建user detail
            UserDetailCreateReqVO createReqVO = MemberAuthConvert.INSTANCE.convertDetailUserVO(adminUserDO, memberAuthDO);
            userdetailservice.createUserDetail(createReqVO);
        }else if(status.getType() == MemberAuthBizTypeEnum.REJECT.getType()){
            MemberAuthDO memberAuthDO = authMapper.selectById(id);
            memberAuthDO.setStatus(MemberAuthBizTypeEnum.REJECT.getType());
            memberAuthDO.setReason(reason);
            authMapper.updateById(memberAuthDO);
        }else {
            throw exception(MEMBER_AUTH_PARAM_ERROR);
        }
    }

    @Override
    public void updateAuth(MemberAuthUpdateReqVO updateReqVO) {
        // 校验存在
        validateAuthExists(updateReqVO.getId());
        // 更新
        MemberAuthDO updateObj = MemberAuthConvert.INSTANCE.convert(updateReqVO);
        authMapper.updateById(updateObj);
    }

    @Override
    public void deleteAuth(Long id) {
        // 校验存在
        validateAuthExists(id);
        // 删除
        authMapper.deleteById(id);
    }

    private void validateAuthExists(Long id) {
        if (authMapper.selectById(id) == null) {
            throw exception(AUTH_NOT_EXISTS);
        }
    }

    private void validateShopAuthExists(Long id) {
        if(shopAuthMapper.selectById(id) == null){
            throw exception(AUTH_NOT_EXISTS);
        }
    }

    @Override
    public MemberAuthDO getAuth(Long id) {
        return authMapper.selectById(id);
    }

    @Override
    public MemberAuthDO getAuthByMemberId(Long memberId){
        MemberUserRespDTO memberUserRespDTO = memberUserApi.getUser(memberId);
        if(memberUserRespDTO == null){
            return null;
        }

        // 数据清空原因
        UserDetailDO userDetailDo = userdetailservice.getUserDetailByMobile(memberUserRespDTO.getMobile());
        if(userDetailDo == null){
            MemberAuthDO memberAuthDO = authMapper.selectOne(MemberAuthDO::getMemberId, memberId);
            if(memberAuthDO == null){
                return null;
            }else{
                if(memberAuthDO.getCreateTime().isBefore(LocalDateTime.of(2024, 8, 1, 12, 0, 0))){
                    return null;
                }else{
                    return memberAuthDO;
                }
            }
        }else{
            MemberAuthDO memberAuthDO = authMapper.selectOne(MemberAuthDO::getMemberId, memberId);
            if(memberAuthDO == null){
                memberAuthDO = new MemberAuthDO();
                memberAuthDO.setMemberId(memberId);
                memberAuthDO.setPicUrl(userDetailDo.getPicUrl());
                memberAuthDO.setLearnTime(userDetailDo.getLearnTime());
                memberAuthDO.setRealName(userDetailDo.getRealName());
                memberAuthDO.setIdBack(userDetailDo.getIdBack());
                memberAuthDO.setIdFront(userDetailDo.getIdFront());
                memberAuthDO.setIdNumber(userDetailDo.getIdNumber());
                memberAuthDO.setStatus(1);
                memberAuthDO.setAreaId(userDetailDo.getAreaId());

                authMapper.insert(memberAuthDO);
                return memberAuthDO;
            }else{
                return memberAuthDO;
            }
        }
    }

    @Override
    public List<MemberAuthDO> getAuthList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return ListUtil.empty();
        }
        return authMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<MemberAuthDO> getAuthPage(MemberAuthPageReqVO pageReqVO) {
        return authMapper.selectPage(pageReqVO);
    }

    @Override
    public List<MemberAuthDO> getAuthList(MemberAuthExportReqVO exportReqVO) {
        return authMapper.selectList(exportReqVO);
    }

    @Override
    public void updateShopAuth(@Valid MemberShopAuthUpdateReqVO updateReqVO){
        validateShopAuthExists(updateReqVO.getId());
        // 更新
        MemberShopAuthDO updateObj = MemberShopAuthConvert.INSTANCE.convert(updateReqVO);
        shopAuthMapper.updateById(updateObj);
    }

    @Override
    public Long createShopAuth(MemberShopAuthCreateReqVO createReqVO){
        tenantService.validTenantNameDuplicate(createReqVO.getShopName(), null);

        Long memberId = createReqVO.getMemberId();
        if(memberId != createReqVO.getMemberId()){
            throw exception(MEMBER_ID_ERROR);
        }

        MemberShopAuthDO memberShopAuthDO = shopAuthMapper.selectOne(new LambdaQueryWrapperX<MemberShopAuthDO>()
                .eq(MemberShopAuthDO::getMemberId, memberId));

        if(memberShopAuthDO != null){
            if(memberShopAuthDO.getStatus() == MemberAuthShopBizTypeEnum.AUTH.getType()){
                throw exception(MEMBER_AUTH_EXISTS);
            }
        }

        MemberUserRespDTO memberUserRespDTO = memberUserApi.getUser(memberId);
        if(memberUserRespDTO == null){
            throw exception(MEMBER_NOT_EXISTS);
        }

        if(memberUserRespDTO.getMobile() == null){
            throw exception(MEMBER_NOT_BAND_MOBILE);
        }

        AdminUserDO adminUserDO = adminUserService.getUserByMobile(memberUserRespDTO.getMobile());
        if(adminUserDO == null){
            throw exception(MEMBER_NOT_BIND_USER);
        }

        TenantDO tenantDO = tenantService.getTenantByUserId(adminUserDO.getId());
        if(tenantDO != null){
            throw exception(MEMBER_HAS_SHOP);
        }

        // 插入
        memberShopAuthDO = MemberShopAuthConvert.INSTANCE.convert(createReqVO);
        shopAuthMapper.insert(memberShopAuthDO);
        // 返回
        return memberShopAuthDO.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditMemberShopAuth(Long id, MemberAuthShopBizTypeEnum status, String reason){
        validateShopAuthExists(id);

        // 1:审核通过 2:审核拒绝 3：参数错误
        //todo 短信通知
        if(status.getType() == MemberAuthShopBizTypeEnum.SUCCESS.getType()){
            MemberShopAuthDO shopAuthDO = shopAuthMapper.selectById(id);
            shopAuthDO.setStatus(MemberAuthBizTypeEnum.SUCCESS.getType());
            shopAuthMapper.updateById(shopAuthDO);
            // 1 前置一定是有user账号的, 绑定的mobile
            MemberUserRespDTO memberUserRespDTO = memberUserApi.getUser(shopAuthDO.getMemberId());
            AdminUserDO adminUserDO = adminUserService.getUserByMobile(memberUserRespDTO.getMobile());

            // 2 创建tenant
            TenantOnlyCreateReqVO createReqVO = MemberShopAuthConvert.INSTANCE.convertTenantCreate(shopAuthDO, adminUserDO);
            //todo package id
            //todo time
            Long tenantId = tenantService.createOnlyTenant(createReqVO);

            // 3 创建tenant detail
            TenantDetailCreateReqVO detailCreateReqVO = MemberShopAuthConvert.INSTANCE.convertTenantDetailCreate(shopAuthDO, adminUserDO);
            detailCreateReqVO.setTenantId(tenantId);
            tenantDetailService.createTenantDetail(detailCreateReqVO);

            // 更新 member tenantid
            memberUserService.updateUserTenantId(memberUserRespDTO.getId(), tenantId);

            // 更新 user tenantid
            adminUserService.updateUserTenantId(adminUserDO.getId(), tenantId);

        }else if(status.getType() == MemberAuthShopBizTypeEnum.REJECT.getType()){
            MemberShopAuthDO shopAuthDO = shopAuthMapper.selectById(id);
            shopAuthDO.setStatus(MemberAuthBizTypeEnum.REJECT.getType());
            shopAuthDO.setReason(reason);
            shopAuthMapper.updateById(shopAuthDO);
        }else {
            throw exception(MEMBER_AUTH_PARAM_ERROR);
        }
    }

    @Override
    public PageResult<MemberShopAuthDO> getMemberShopAuthPage(MemberShopAuthPageReqVO pageReqVO){
        return shopAuthMapper.selectPage(pageReqVO);
    }

    @Override
    public MemberShopAuthDO getMemberShopAuthByMemberId(Long memberId){
        MemberUserRespDTO memberUserRespDTO = memberUserApi.getUser(memberId);
        if(memberUserRespDTO == null){
            return null;
        }

        // 数据清空原因
        TenantDetailDO tenantDetailDO = tenantDetailService.getTenantDetailByMobile(memberUserRespDTO.getMobile());
        if(tenantDetailDO == null){
            MemberShopAuthDO shopAuthDO = shopAuthMapper.selectOne(MemberShopAuthDO::getMemberId, memberId);
            if(shopAuthDO == null){
                return null;
            }else{
                if(shopAuthDO.getCreateTime().isBefore(LocalDateTime.of(2024, 8, 1, 12, 0, 0))){
                    return null;
                }else{
                    return shopAuthDO;
                }
            }
        }else {
            MemberShopAuthDO shopAuthDO = shopAuthMapper.selectOne(MemberShopAuthDO::getMemberId, memberId);
            if(shopAuthDO == null){
                shopAuthDO = new MemberShopAuthDO();
                shopAuthDO.setMemberId(memberId);
                shopAuthDO.setAreaId(Integer.valueOf(tenantDetailDO.getAreaId().intValue()));
                shopAuthDO.setShopName(tenantDetailDO.getName());
                shopAuthDO.setPicUrl(tenantDetailDO.getPicUrl());
                shopAuthDO.setAddress(tenantDetailDO.getAddress());
                shopAuthDO.setDescription(tenantDetailDO.getDescription());
                shopAuthDO.setJiushiCount(tenantDetailDO.getJiushiCount());
                shopAuthDO.setRoomCount(tenantDetailDO.getRoomCount());
                shopAuthDO.setSize(tenantDetailDO.getSize());
                shopAuthDO.setStatus(1);
                shopAuthDO.setTitleUrl(tenantDetailDO.getTitleUrl());
                shopAuthDO.setVideoUrl(tenantDetailDO.getVideoUrl());

                shopAuthMapper.insert(shopAuthDO);

                return shopAuthDO;
            }else{
                return shopAuthDO;
            }
        }
    }
}
